import random
import string

from django.db.models import  Q,Max,Min,Count,Avg,Sum

from django.shortcuts import render
from django.http import JsonResponse
from rest_framework.parsers import JSONParser
from rest_framework.decorators import api_view

from .models import User, Book, Author
import logger
import base64
from django.core.paginator import Paginator,PageNotAnInteger,EmptyPage#分页用到的3个模块
# Create your views here.

def showregisterhtml(request):
    return render(request, 'register.html')

# 判空的方法
def is_empty(c):
    return c is None or str(c).strip() == ''

#为密码加密的方法
def b64encodes(c):
    #先把字符串转成字节码
    by=bytes(c,encoding='utf-8')
    b64c=base64.b64encode(by).decode('utf-8')
    return b64c

from django.core.signing import Signer
from django.core.cache import cache
from datetime import timedelta

#产生token的方法
def createtoken(name):
    #首先是产生一个8位的随机字符串
    logger.logger.info(f'看看这个ascii_letters是什么内容：{string.ascii_letters}')
    randomstr=''.join(random.choices(string.ascii_letters,k=8))
    logger.logger.info(f"看看这个随机字符串是什么内容：{randomstr}")
    #产生token
    token=Signer().sign(randomstr+name)
    #把这个token设置到服务器的缓存中
    cache.set(f'test_{name}',token,timeout=timedelta(minutes=100).total_seconds())
    return token

#鉴权
def checktoken(request):
    #从前端的请求中获取token内容
    logger.logger.info(f"request.META是什么内容：{request.META}")
    reqtoken=request.META.get('HTTP_TOKEN')
    logger.logger.info(f"reqtoken长什么样子：{reqtoken}")
    #如果前端没有传token，会进入下面这个分支
    if reqtoken is None:
        return False,'XXXXX'
    #对获取到的token进行反签名
    untoken=Signer().unsign(reqtoken)
    logger.logger.info(f"反签名后的内容：{untoken}")
    #从反签名后的内容获取用户名name
    name=untoken[8:]
    #从缓存中获取token
    cachetoken=cache.get(f'test_{name}')
    #如果进入下面这个分支，说明缓存中的token已经过期，不存在了
    if cachetoken is None:
        return False,'XXXXX'
    #如果缓存中的token还存在
    return True,name

@api_view(['GET'])
def getpageuserinfo(request):
    #得到页码
    page=request.GET.get('page')
    #得到每页显示的数据条数
    pagesize=request.GET.get('pagesize')
    #得到所有的数据
    allobj=User.objects.filter()
    #生成一个分页的对象
    pageobj=Paginator(allobj,pagesize)
    #用一个异常处理
    try:
        singleobj=pageobj.page(page)
    except PageNotAnInteger:
        singleobj=pageobj.page(1)
    except EmptyPage:
        singleobj=pageobj.page(pageobj.num_pages)
    #定义一个空列表，用于存数
    lis=[]
    logger.logger.info(f"看看这个数据长什么样子：{singleobj}")
    logger.logger.info(f"看看singleobj.object_list：{singleobj.object_list}")
    for item in singleobj.object_list:
        lis.append({
            'name':item.name,
            'password':item.password,
            'gender':item.gender,
            'age':item.age
        })
    return JsonResponse({
        'message':"查询成功",
        'data':lis
    })


@api_view(['GET'])
def login(request):
    # data=JSONParser().parse(request)
    # logger.logger.info(f"前端没有穿JSON数据，看看解释后的数据：{data}")
    logger.logger.info(f"request.GET是什么内容：{request.GET}")
    name=request.GET.get('name')
    password=request.GET.get('password')
    # 为空的判断
    if is_empty(name) or is_empty(password):
        return JsonResponse({
            'msg': "必填项参数不能为空"
        }, status=400)
    if User.objects.filter(name=name).exists() is False:
        return JsonResponse({
            'msg':'用户不存在'
        })
    #把用户对象查询出来
    obj=User.objects.get(name=name)
    #加密密码
    b64password=b64encodes(password)
    #比对密码
    if obj.password==b64password:
        #产生token
        token=createtoken(name)
        logger.logger.info(f"产生的token为：{token}")
        return JsonResponse({
            'msg':"登录成功",
            'token':token
        })
    else:
        return JsonResponse({
            'msg': "密码错误",
        },status=409)

# 视图函数
@api_view(['POST'])
def adduser(request):
    flag,name=checktoken(request)
    if flag == False:
        return JsonResponse({
            'msg':"未登录，无法添加用户"
        },status=401)

    logger.logger.info(f"看看获得的Request是什么样子：{request}")
    data = JSONParser().parse(request)
    logger.logger.info(f"看看获得的data是什么样子：{data}")

    name = data.get('name')
    password = data.get('password')
    gender = data.get('gender')
    age = data.get('age')

    #为空的判断
    if is_empty(name) or is_empty(password) or is_empty(gender) or is_empty(age):
        return JsonResponse({
            'msg':"必填项参数不能为空"
        },status=400)
    #判重
    if User.objects.filter(name=name).exists():
        return JsonResponse({
            'message':"用户名已存在"
        },status=409)

    try:
        b64password=b64encodes(password)
        #向数据表插入数据
        User(name=name, password=b64password, gender=gender, age=age).save()
        return JsonResponse({
            'msg': '用户添加成功'
        })
    except Exception as e:
        return JsonResponse({
            'msg':"服务端内部错误"
        },status=500)

@api_view(['GET'])
def getuserinfo(request):
    flag,name=checktoken(request)
    if flag is False:
        return JsonResponse({
            'msg':"你还未登录"
        },status=401)
    # 查询出所有的数据对象
    allobj = User.objects.filter()
    # 定义一个空列表用于存数
    lis = []
    # 用一个for循环，把所有数据添加到lis列表中
    for item in allobj:
        lis.append({
            "姓名": item.name,
            "密码": item.password,
            "性别": item.gender,
            "年龄": item.age
        })
    return JsonResponse({
        "msg": "查询成功",
        "data": lis
    })


# 修改
@api_view(['PUT'])
def modifyuser(request):
    data = JSONParser().parse(request)
    userid = data.get('userid')
    name = data.get('name')
    password = data.get('password')
    gender = data.get('gender')
    age = data.get('age')

    if is_empty(userid):
        return JsonResponse({
            'msg': "用户id不能为空"
        })
    # 根据userid查询出数据对象
    obj = User.objects.get(id=userid)
    logger.logger.info(f"看看查询出来的单个数据对象：{obj}")
    # 如果name不为空
    if is_empty(name) is False:
        obj.name = name
    # 如果password不为空
    if is_empty(password) is False:
        obj.password = password
    # 如果gender不为空
    if is_empty(gender) is False:
        obj.gender = gender
    # 如果age不为空
    if is_empty(age) is False:
        obj.age = age

    # 进行保存
    obj.save()
    # 返回修改后的内容
    return JsonResponse({
        'msg': "修改后的数据",
        'name': obj.name,
        'password': obj.password,
        'gender': obj.gender,
        'age': obj.age,
    })


@api_view(['DELETE'])
def deleteuser(request):
    data = JSONParser().parse(request)
    userid = data.get("userid")
    if is_empty(userid):
        return JsonResponse({
            "msg": "用户id不能为空"
        }, status=400)
    obj = User.objects.get(id=userid)
    obj.delete()
    return JsonResponse({
        "msg": "删除成功"
    }, status=200)

@api_view(['POST'])
def addbook(request):
    data=JSONParser().parse(request)
    name=data.get('name')
    price=data.get('price')
    category=data.get('category')
    pubishdate=data.get('pubishdate')
    pubisher=data.get('pubisher')
    authorid=data.get('authorid')

    Book(name=name,price=price,category=category,pubishdate=pubishdate,pubisher=pubisher,author_id=authorid).save()

    return JsonResponse({
        'msg':"添加书籍成功"
    })

@api_view(['GET'])
def getauthorbook(request):
    # name=request.GET.get('name')
    #根据姓名查询出作者对象
    # obj=Author.objects.get(name=name)
    #查询出所有作者对象
    objs=Author.objects.filter()
    # logger.logger.info(f"查看这个作者下关联的书的数据的对象：{obj.book.all()}")
    #定义一个空列表，用于存储数据用
    lis=[]
    for obj in objs:
        for item in obj.book.all():
            lis.append({
                'authname':obj.name,
                'authorgender':obj.gender,
                'authorage':obj.age,
                'authoraddress':obj.address,
                'bookname':item.name,
                'bookprice':item.price,
                'bookcategory':item.category,
                'bookpubishdate':item.pubishdate,
                'bookcreatetime':item.createtime,
                'bookupdatetime':item.updatetime,
            })

    return JsonResponse({
        'msg':'查询成功',
        'data':lis
    })

@api_view(['GET'])
def getbookauthor(request):
    name=request.GET.get('name')
    obj=Book.objects.get(name=name)
    return JsonResponse({
        'name':obj.name,
        'price':obj.name,
        'category':obj.category,
        'authorname':obj.author.name,
        'authorgender':obj.author.gender,
        'authorage':obj.author.age,
        'authoraddress':obj.author.address,
    })

@api_view(['PUT'])
def modifybook(request):

    data = JSONParser().parse(request)
    bookid = data.get('bookid')

    name = data.get('newname')

    if Book.objects.filter(name=name).exists():
        return JsonResponse({
            'msg': "书名已存在无法修改"
        })

    obj = Book.objects.get(id=bookid)
    obj.name = name
    obj.save()

    return JsonResponse({
        'msg': "修改成功"
    })

@api_view(['GET'])
def getbookinfo(request):
    page = request.GET.get('page')
    pagesize = request.GET.get('pagesize')

    allobj = Book.objects.filter()

    pageobj = Paginator(allobj, pagesize)

    try:
        singlepage = pageobj.page(page)
    except PageNotAnInteger:
        singlepage = pageobj.page(1)
    except EmptyPage:
        singlepage = pageobj.page(pageobj.num_pages)

    lis = []
    for item in singlepage.object_list:
        lis.append({
            'name': item.name,
            'price': item.price,
            'category': item.category,
            'pubisher': item.pubisher,
        })
    return JsonResponse({
        'msg': "查询成功",
        'data': lis
    })

@api_view(['GET'])
def getbookcontent(request):
    name=request.GET.get('name')
    obj=Book.objects.filter(name__contains=name)
    lis=[]
    for item in obj:
        lis.append({
            'name':item.name,
            'price':item.price,
            'category':item.category,
            'pubisher':item.pubisher,
        })
    return JsonResponse({
        'msg':'查询成功',
        'data':lis
    })

@api_view(['GET'])
def getbookcontentdate(request):
    starttime=request.GET.get('startdate')
    enddate=request.GET.get('enddate')
    obj=Book.objects.filter(pubishdate__gte=starttime,pubishdate__lte=enddate)
    lis=[]
    for item in obj:
        lis.append({
            'name':item.name,
            'price':item.price,
            'category':item.category,
            'pubisher':item.pubisher,
        })
    return JsonResponse({
        'msg':'查询成功',
        'data':lis
    })
#多条件查询
@api_view(['GET'])
def getbookbycondition(request):
    name=request.GET.get('name')
    price=request.GET.get('price')
    category=request.GET.get('category')
    pubisher=request.GET.get('pubisher')
    dic={}
    if is_empty(name) is False:
        dic['name__contains']=name
    if is_empty(price) is False:
        dic['price__gte']=price
    if is_empty(category) is False:
        dic['category'] = category
    if is_empty(pubisher) is False:
        dic['pubisher']=pubisher

    allobj=Book.objects.filter(**dic)

    lis=[]
    for item in allobj:
        lis.append({
            'name':item.name,
            'price':item.price,
            'category':item.category,
            'pubisher':item.pubisher,
            'authorname':item.author.name,
        })

    return JsonResponse({
        'msg':"查询成功",
        'data':lis
    })

@api_view(['PUT'])
def updatebook(request):
    data=JSONParser().parse(request)
    id=data.get('bookid')
    name=data.get('name')
    price=data.get('price')
    category=data.get('category')
    pubisher=data.get('pubisher')
    try:
        if is_empty(id):
            return JsonResponse({
                'msg': '书籍id不能为空'
            },status=400)
        obj=Book.objects.get(id=id)
    except:
        return JsonResponse({
            'msg':'服务端内部错误'
        })
    if is_empty(name) is False:
        if Book.objects.filter(name=name).exists():
            return JsonResponse({
                'msg':'书名已存在'
            },status=400)
        obj.name=name
    if is_empty(price) is False:
        obj.price=price
    if is_empty(category) is False:
        obj.category=category
    if is_empty(pubisher) is False:
        obj.pubisher=pubisher
    #保存修改的数据
    obj.save()
    return JsonResponse({
        'msg':'修改成功'
    })


@api_view(['GET'])
def getbookinfobycondition(request):
    name=request.GET.get('name')
    price=request.GET.get('price')
    allobjs=Book.objects.filter(Q(name=name) | Q(price=price))
    lis=[]
    for item in allobjs:
        lis.append({
            'name':item.name,
            'price':item.price,
            'category':item.category,
            'publiser':item.pubisher,
            'authorname':item.author.name
        })
    return  JsonResponse({
        'msg':'查询成功',
        'data':lis
    })

@api_view(['GET'])
def groupbyselect(request):
    data=Book.objects.values('pubisher').annotate(maxprice=Max('price'),minprice=Min('price'),avgprice=Avg('price'),totalprice=Sum('price'),nums=Count('id'))
    logger.logger.info(f"data数据：{data}")
    lis=[]
    for item in data:
        lis.append({
            '出版社的名字': item.get('pubisher'),
            '价格最大值': '{:.2f}'.format(item.get('maxprice')),
            '价格最小值': '%.2f' % item.get('minprice'),
            '价格平均值': '%.2f' % item.get('avgprice'),
            '价格总数': '%.2f' % item.get('totalprice'),
            '出版书籍数量': item.get('nums'),
        })

    return JsonResponse({
        'msg':'查询成功',
        'data':lis
    })

@api_view(['GET'])
def cha(request):
    objs=Book.objects.filter()
    lis=[]
    for item in objs:
        lis.append({
            'id':item.id,
            'name':item.name,
            'price':item.price,
            'category':item.category,
            'pubishdata':item.pubisherdata,
            'pubisher':item.pubisher,
            'author':item.author.name,
            'createtime':item.createtime,
            'updatetime':item.updatetime
        })
    return JsonResponse({
        'msg': '查询成功',
        'data': lis
    })

@api_view(['GET'])
def getbooklist(request):
    allobj=Book.objects.filter()
    lis=[]
    for obj in allobj:
        lis.append({
            'id':obj.id,
            'name':obj.name,
            'price':obj.price,
            'category':obj.category,
            'pubishdate':obj.pubishdate,
            'pubisher':obj.pubisher,
            'author':obj.author.name,
            'createtime':obj.createtime,
            'updatetime':obj.updatetime
        })
    return JsonResponse({
        'msg': '查询成功',
        'data': lis
    })

@api_view(['GET'])
def getpagebooklist(request):
    #得到页码
    page=request.GET.get('_page')
    #得到每页显示的数据条数
    pagesize=request.GET.get('_per_page')

    name=request.GET.get('name')
    authorname=request.GET.get('authorname')
    pubisher=request.GET.get('pubisher')
    dic={}
    if is_empty(name) is False:
        dic['name']=name
    if is_empty(pubisher) is False:
        dic['pubisher'] = pubisher
    if is_empty(authorname) is False:
        if Author.objects.filter(name=authorname).exists():
            obj=Author.objects.get(name=authorname)
            dic['author_id']=obj.id
        else:
            dic['author_id']=-1
    # 得到所有的数据
    allobj=Book.objects.filter(**dic)
    #生成一个分页的对象
    pageobj=Paginator(allobj,pagesize)
    #用一个异常处理
    try:
        singleobj=pageobj.page(page)
    except PageNotAnInteger:
        singleobj=pageobj.page(1)
    except EmptyPage:
        singleobj=pageobj.page(pageobj.num_pages)
    #定义一个空列表，用于存数
    lis=[]
    logger.logger.info(f"看看这个数据长什么样子：{singleobj}")
    logger.logger.info(f"看看singleobj.object_list：{singleobj.object_list}")
    for obj in singleobj.object_list:
        lis.append({
            'id': obj.id,
            'name': obj.name,
            'price': obj.price,
            'category': obj.category,
            'pubishdate': obj.pubishdate,
            'pubisher': obj.pubisher,
            'author': obj.author.name,
            'createtime': obj.createtime,
            'updatetime': obj.updatetime
        })
    return JsonResponse({
        'message':"查询成功",
        'data':lis,
        'items': allobj.count()
    })

@api_view(['POST'])
def addbookvue(request):

    flag,name=checktoken(request)
    if flag is False:
        return JsonResponse({
            'msg':'未登录，请先登录'
        },status=401)

    data=JSONParser().parse(request)
    name=data.get('name')
    price=data.get('price')
    category=data.get('category')
    pubishdate=data.get('pubishdate')
    pubisher=data.get('pubisher')
    author=data.get('author')

    Book(name=name,price=price,category=category,pubishdate=pubishdate,pubisher=pubisher,author_id=author).save()

    return JsonResponse({
        'msg':'添加成功'
    })

@api_view(['DELETE'])
def deletebookvue(request,itemid):
    bookobj=Book.objects.get(id=itemid)
    bookobj.delete()
    return JsonResponse({
        'msg':'删除成功'
    })

@api_view(['GET'])
def getbookinfovue(request,itemid):
    obj=Book.objects.get(id=itemid)
    return JsonResponse({
        'name':obj.name,
        'price':obj.price,
        'category':obj.category,
        'pubishdate':obj.pubishdate,
        'pubisher':obj.pubisher,
        'author':obj.author.id
    })

@api_view(['PUT'])
def updatebookvue(request,itemid):
    bookobj=Book.objects.get(id=itemid)
    data=JSONParser().parse(request)
    name=data.get('name')
    price=data.get('price')
    category=data.get('category')
    pubishdate=data.get('pubishdate')
    pubisher=data.get('pubisher')
    author=data.get('author')
    if is_empty(name) is False:
        bookobj.name=name
    if is_empty(price) is False:
        bookobj.price=price
    if is_empty(category) is False:
        bookobj.category=category
    if is_empty(pubishdate) is False:
        bookobj.pubishdate=pubishdate
    if is_empty(pubisher) is False:
        bookobj.pubisher=pubisher
    if is_empty(author) is False:
        bookobj.author_id=author
    bookobj.save()
    return JsonResponse({
        'msg':'修改成功'
    })

@api_view(['GET'])
def getpubishervue(request):
    pubisherdata=Book.objects.values('pubisher').annotate(publishname=Max('pubisher'))
    logger.logger.info(f"获取到的分组后的数据：{pubisherdata}")
    lis=[{'label':'请选择','value':''}]
    for item in pubisherdata:
        lis.append({
            'label':item.get('pubisher'),
            'value':item.get('pubisher')
        })
    return JsonResponse({
        'msg':'查询成功',
        'data':lis
    })






